package org.valire.db;

import java.sql.Connection;
import java.sql.DatabaseMetaData;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;

import javax.sql.DataSource;

import dnl.toolbox.lang.ClassPathHacker;

public class DbMetaDataUtil {

	private JdbcConnectionInfo jdbcConnectionInfo;
	private DataSource dataSource;

	private Connection c = null;

	public DbMetaDataUtil(JdbcConnectionInfo jdbcConnectionInfo) {
		if (jdbcConnectionInfo == null) {
			throw new IllegalArgumentException();
		}
		this.jdbcConnectionInfo = jdbcConnectionInfo;
	}

	public DbMetaDataUtil(DataSource dataSource) {
		this.dataSource = dataSource;
	}

	public List<String> listCatalogs() {
		List<String> l = new ArrayList<String>();
		try {
			c = getConnection();
			DatabaseMetaData metaData = c.getMetaData();
			ResultSet rs = metaData.getCatalogs();
			while (rs.next()) {
				l.add(rs.getString("TABLE_CAT"));
			}
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
		
		}
		return l;
	}

	public List<String> listTables() {
		List<String> l = new ArrayList<String>();
		List<String> listCatalogs = listCatalogs();
		for (String cat : listCatalogs) {
			List<String> tables = listTables(cat);
			for (String table : tables) {
				l.add(cat + "." + table);
			}
		}
		return l;
	}

	public List<String> listTables(String catalog) {
		List<String> l = new ArrayList<String>();
		try {
			c = getConnection();
			DatabaseMetaData metaData = c.getMetaData();
			ResultSet rs = metaData.getTables(catalog, null, null, new String[] { "TABLE" });
			while (rs.next()) {
				l.add(rs.getString("TABLE_NAME"));
			}
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			
		}
		return l;
	}

	public Connection getConnection() throws Exception {
		if(c != null){
			return c;
		}
		if (dataSource != null) {
			return dataSource.getConnection();
		}
		if (jdbcConnectionInfo.getDriverPath() != null) {
			ClassPathHacker.addFile(jdbcConnectionInfo.getDriverPath());
		}
		Connection con = null;
		Class.forName(jdbcConnectionInfo.getDriver());
		con = DriverManager.getConnection(jdbcConnectionInfo.getJdbcUrl(), jdbcConnectionInfo
				.getUser(), jdbcConnectionInfo.getPassword());

		return con;
	}

	public void closeConnection(){
		if (c != null) {
			try {
				c.close();
			} catch (SQLException e) {
				e.printStackTrace();
			}
		}
	}
}
